package com.weichen.studentgameexchange.comment.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.weichen.studentgameexchange.comment.dao.CommentMapper;
import com.weichen.studentgameexchange.comment.entity.*;
import com.weichen.studentgameexchange.comment.entity.vo.AddCommentVo;
import com.weichen.studentgameexchange.comment.entity.vo.CommentVo;
import com.weichen.studentgameexchange.comment.entity.vo.UserCommentVo;
import com.weichen.studentgameexchange.comment.feign.MemberFeignClient;
import com.weichen.studentgameexchange.comment.service.ICommentService;
import com.weichen.studentgameexchange.common.common.Result;
import com.weichen.studentgameexchange.common.enums.CommentStatus;
import com.weichen.studentgameexchange.common.exception.ServiceException;
import com.weichen.studentgameexchange.member.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 惟尘
 * @since 2025-02-05
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {

    @Autowired
    CommentMapper commentMapper;

    @Autowired
    MemberFeignClient memberFeignClient;
    /**
     * 查询审核日志
     *
     * @param commentId
     * @return
     */
    @Override
    public CommentAuditLog adminSelectOne(Long commentId) {
        Comment one = Db.lambdaQuery(Comment.class)
                .eq(Comment::getCommentId, commentId)
                .one();
        CommentAuditLog commentAuditLog = new CommentAuditLog();
        commentAuditLog.setCommentId(commentId);
        commentAuditLog.setOldStatus(one.getStatus());
        return commentAuditLog;
    }

    @Override
    public Result userPage(Integer page, Integer size) {
        Page<Comment> commentPage = new Page<>(page, size);
        LambdaQueryWrapper<Comment> commentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        commentLambdaQueryWrapper.orderByDesc(Comment::getCommentId).eq(Comment::getStatus, CommentStatus.CREATE);
        Page<Comment> selectPage = commentMapper.selectPage(commentPage, commentLambdaQueryWrapper);
        List<Comment> records = selectPage.getRecords();
        List<CommentVo> result = new ArrayList<>();
        List<Comment> comments = records
                .stream()
                .map(comment -> {
                    CommentVo copyProperties = BeanUtil.copyProperties(comment, CommentVo.class);
                    User user = memberFeignClient.getUserById(copyProperties.getUserId());
                    copyProperties.setUsername(user.getUsername());
                    copyProperties.setAvatar(user.getAvatar());
                    int likeCount = Db.lambdaQuery(CommentLike.class)
                            .eq(CommentLike::getCommentId, comment.getCommentId())
                            .list()
                            .size();
                    int replyCount = Db.lambdaQuery(CommentReply.class)
                            .eq(CommentReply::getCommentId, comment.getCommentId())
                            .list()
                            .size();
                    copyProperties.setLikeCount(likeCount);
                    copyProperties.setReplyCount(replyCount);
                    result.add(copyProperties);
                    return comment;
                }).toList();
        Page<CommentVo> voPage = new Page<>(page, size);
        voPage.setTotal(selectPage.getTotal());
        voPage.setSize(selectPage.getSize());
        voPage.setCurrent(selectPage.getCurrent());
        voPage.setRecords(result);
        return Result.success(voPage);
    }

    @Override
    public Result userAdd(AddCommentVo addCommentVo) {
        Comment comment = BeanUtil.copyProperties(addCommentVo, Comment.class);
        commentMapper.insert(comment);
        return Result.success();
    }

    @Override
    public Result userDeleteOne(Long commentId) {
        adminDeleteOne(commentId);
        return Result.success();
    }

    @Override
    public Result userSelect(Long userId) {
        List<Comment> comments = Db.lambdaQuery(Comment.class)
                .eq(Comment::getUserId, userId)
                .list();
        List<UserCommentVo> vos = new ArrayList<>();
        comments.forEach(comment -> {
            UserCommentVo vo = BeanUtil.copyProperties(comment, UserCommentVo.class);
            vos.add(vo);
        });
        return Result.success(vos);
    }

    /**
     * 分页查询
     *
     * @param keyword
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<Comment> adminPage(String keyword, Integer page, Integer size) {
        Page<Comment> commentPage = new Page<>(page, size);
        LambdaQueryWrapper<Comment> commentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        commentLambdaQueryWrapper.orderByDesc(Comment::getCommentId);
        Long key = null;
        if (!StrUtil.isBlankIfStr(keyword)) {
            try {
                key = Long.parseLong(keyword);
            } catch (NumberFormatException e) {
                throw new ServiceException("字符串不是一个有效的数字！");
            }
        }
        commentLambdaQueryWrapper.eq(key != null, Comment::getUserId, key);
        Page<Comment> selectPage = commentMapper.selectPage(commentPage, commentLambdaQueryWrapper);
        List<Comment> records = selectPage.getRecords();
        List<Comment> result = new ArrayList<>();
        List<Comment> comments = records
                .stream()
                .map(comment -> {
                    Comment copyProperties = BeanUtil.copyProperties(comment, Comment.class);
                    int likeCount = Db.lambdaQuery(CommentLike.class)
                            .eq(CommentLike::getCommentId, comment.getCommentId())
                            .list()
                            .size();
                    int replyCount = Db.lambdaQuery(CommentReply.class)
                            .eq(CommentReply::getCommentId, comment.getCommentId())
                            .list()
                            .size();
                    copyProperties.setLikeCount(likeCount);
                    copyProperties.setReplyCount(replyCount);
                    result.add(copyProperties);
                    return comment;
                }).toList();
        selectPage.setRecords(result);
        return selectPage;
    }

    /**
     * 删除单个评论
     *
     * @param commentId
     */
    @Override
    public void adminDeleteOne(Long commentId) {
        Comment comment = Db.lambdaQuery(Comment.class)
                .eq(Comment::getCommentId, commentId)
                .one();
        if (comment == null)
            throw new ServiceException("评论不存在！");
        List<CommentReply> list = Db.lambdaQuery(CommentReply.class)
                .eq(CommentReply::getCommentId, commentId)
                .list();
        if (list.size() > 0) {
            List<Long> replyIds = list.stream().map(CommentReply::getReplyId).toList();
            Db.lambdaUpdate(CommentReplyLike.class)
                    .in(CommentReplyLike::getReplyId, replyIds)
                    .remove();
            Db.removeByIds(list, CommentReply.class);
        }
        List<CommentLike> list1 = Db.lambdaQuery(CommentLike.class)
                .eq(CommentLike::getCommentId, commentId)
                .list();
        if (list1.size() > 0)
            Db.removeByIds(list1, CommentLike.class);
        List<CommentReport> list2 = Db.lambdaQuery(CommentReport.class)
                .eq(CommentReport::getCommentId, commentId)
                .list();
        if (list2.size() > 0)
            Db.removeByIds(list2, CommentReport.class);
        Db.lambdaUpdate(CommentAuditLog.class)
                .eq(CommentAuditLog::getCommentId, commentId)
                .remove();
        Db.lambdaUpdate(Comment.class)
                .eq(Comment::getCommentId, commentId)
                .remove();
    }


}
